<?php

namespace App\Models\Access\User;

use Dompdf\Exception;
use FontLib\TrueType\Collection;
use function foo\func;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Support\Facades\DB;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Models\Access\Role\Role;///////////
use App\Models\Access\User\Traits\UserAccess;
use App\Models\Access\User\Traits\Relationship\UserRelationship;
use App\Models\Access\User\Traits\UserOgz;
use App\Models\App;
use App\Models\Access\User\Traits\UserRelate;

class User extends Authenticatable
{
    use Notifiable,UserAccess,UserRelationship,softDeletes;

    use UserOgz,UserRelate;

    const SUPER_ADMIN = 1;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password', 'real_name', 'phone'
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    protected $dates = ['deleted_at'];

    /**
     * 用户列表信息
     * @param string $where
     * @return array
     */
    public static function getList($where,$limit,$fields='*'){

        //模型关联查询
        //$user = User::with('roles')->get();
        //whereNotNull and whereNull
        $buider = self::builderWhere($where,$fields);
        // $buider->select($fields);
        return $buider->offset($limit[0])
            ->limit($limit[1])
            ->orderBy('u.created_at','desc')
            ->get();
    }
    /**
     * 记录数
     * @param array $where
     * @return integer
     */
    public static function getCount($where){
        $buider = self::builderWhere($where);
        return $buider->count();

    }

    /**
     * 构建多条件查询条件
     * @param $where
     * @return mixed
     */
    public static function builderWhere ($where,$fields='*'){
        $buider = DB::table('users as u')
            ->select($fields)
            ->leftJoin('assigned_ogzs as ao','ao.user_id','=','u.id')
            ->leftJoin('ogz as o','ao.ogz_id','=','o.id');
        if (!empty($where)){
            $status = isset($where[0]) ? intval($where[0]) : 0;
            if ($status){

                if ($status==1){
                    $buider->whereNull('u.deleted_at');
                    $buider->where('u.status','=',1);
                }
                if ($status==2){
                    $buider->whereNotNull('u.deleted_at');
                    $buider->orWhere('u.status','=',0);
                }
                //分组
                if (isset($where[1]) && $where[1]){

                    $buider->where(function ($query) use ($where) {
                        $query->where('u.name','like','%'.$where[1].'%')
                            ->orWhere('u.real_name','like','%'.$where[1].'%');
                    });
                }
            } else {
                if (isset($where[1]) && $where[1]){
                    $buider->where('u.name','like','%'.$where[1].'%')->orwhere('u.real_name','like','%'.$where[1].'%');
                }
            }
            //全局参数
            if (isset($where[2]) && $where[2])
                $buider->whereIn($where[2][0],$where[2][1]);
        }
        return $buider;
    }

    /**
     * 用户角色
     * @param integer $uid
     */
    public function getUserRoles ($uid){

        $user = User::with('roles')->withTrashed()->find($uid);

        return !empty($user) ? $user->roles : [];
    }

    /**
     * 用户所在机构
     * @param integer $uid
     */
    public function getUserOgzs ($uid){
        $user = User::with('ogzs')->withTrashed()->find($uid);

        return !empty($user) ? $user->ogzs : [];
    }

    /**
     * 修改记录
     * @param array $request
     * @return bool
     */
    public function updateRow($request){
        $user = $this->withTrashed()->find($request->id);
        //update user
        $user->real_name = $request->real_name;
        $user->email = empty($request->email) ? '' :encrypt_func($request->email,$request->name);
        $user->phone = empty($request->phone) ? '' :encrypt_func($request->phone,$request->name);
        return DB::transaction(function() use ($user,$request) {
            $ogzs = $request->ogz_id;
            $user->saveOgz($ogzs);
            //同步角色
            $user->flushRoles($request->roles);
            if ($user->save()) {
                return true;
            }

            throw new \Exception('用户信息更新失败');
        });

    }

    /**
     * 删除记录
     * @param mixed $request
     * @return bool
     */
    public static function deleteRow($request){
        //超级管理员不能删除
        if (intval($request->id) === User::SUPER_ADMIN)
            return false;
        $user = user::find($request->id);
        //避免禁用用户二次进入
        if ($user){
            return DB::transaction(function() use ($user){
                $user->status = 0;
                $user->save();
                $user->delete();
                return true;
            });
        }
        return false;

    }
    /**
     * 激活用户
     * @param mixed $request
     * @return bool
     */
    public static function activeRow($request){
        //超级管理员不存在这操作
        //首次激活
        /*if (intval($request->id)===User::SUPER_ADMIN)
            return false;*/
        $user = User::withTrashed()->find($request->id);
        //避免禁用用户二次进入
        if ($user){
            $user->status = 1;
            $user->deleted_at = NULL;
            if ($user->save()){
                return true;
            }
        }
        return false;

    }
    /**
     * 管辖应用
     * @param $withTrash 是否查询已禁用
     * @return array
     */
    public function hasApps($withTrash)
    {
        $hasApps = [];
        $ogzApp = collect(App::getAppByOgzIds($this->hasOgzs($withTrash),$withTrash))->pluck('id');
        //机构下app覆盖联系人app
        //ogz's app > linkers app
        //权限由大到小,机构下没有app,调用联系人
        $linkerApp = App::getAppByUser($this->id)->pluck('id');
        $hasApps = $ogzApp->merge($linkerApp)->unique()->toArray();

        return $hasApps;
    }
    /**
     * 查询漏洞拥有的状态
     * @return array
     */
    public function hasStatus()
    {
        $hasStatus = [];
        $config = config('access');
        $temp = [];
        foreach ($this->roles as $role){

            if ($role->id === 1){
                $hasStatus = array_keys($config['permissionStatus']);
            }else{
                $temp[] = $role->permissions->pluck('code')->intersect(array_values($config['permissionStatus']));
            }
        }
        $status = array_flip($config['permissionStatus']);
        if (empty($hasStatus)){
            foreach ($temp as $item){
                foreach ($item as $value){

                    $hasStatus[] = $status[$value];
                }
            }
        }
        return array_unique($hasStatus);
    }
    /**
     * 隐藏手机号固定位
     * @param string $phoneNum
     * @param string $new
     */
    public static function hidePhoneKey ($phoneNum){
        $new = '';
        $len = strlen($phoneNum);
        for ($i=0;$i<$len;$i++){
            if ($i>2 && $i < 7){
                $new .= '*';
            }else{

                $new .= $phoneNum[$i];
            }
        }
        return $new;
    }
    /**
     * 插入记录
     * @param mixed $request
     * @return bool
     */
    public function insertRow($request){
        $arrData = $request->input();
        $arrData['email'] = empty($arrData['email']) ? '' :encrypt_func($arrData['email'],$arrData['name']);
        $arrData['phone'] = empty($arrData['phone']) ? '' :encrypt_func($arrData['phone'],$arrData['name']);
        $id = $this->create($arrData)->id;
        $user = $this->find($id);
        return DB::transaction(function() use ($user,$request) {
            $ogzs = $request->ogz_id;
            $user->saveOgz($ogzs);
            //同步角色
            $user->flushRoles($request->roles);
            if ($user->save()) {
                return true;
            }

            throw new \Exception('用户信息更新失败');
        });

    }
    /**
     * 是否绑定外部用户
     * @param int userId
     * @return bool
     */
    public static function checkIsAttacted ($userId){
        $isAttacted = false;
        $isAttacted = User::with('relation')->find($userId)->relation->count() >= 1;
        return $isAttacted;
    }
    /**
     * 查询特定用户
     * @param array $where
     * @return mixed
     */
    public static function getOneUser ($where) {
        $user = collect([]);
        if (is_array($where)) {

            if (DB::table('users')->where($where)->first()){

                $user = collect(DB::table('users')->where($where)->first());
            }
        }
        return $user;
    }

    /**
     * 获取whereIn
     * @param array $ids
     * @param array $sel
     * @return array
     */
    public static function getUserByIds ($sel,$ids){
        $ret = [];
        if (is_array($ids)){
            $ret = self::select($sel)->whereIn('id',$ids)->get();
        }
        return $ret;
    }

    /**
     * 获取多个用户名的字符串
     */
    public static function getNameString ($ids){
        $nameString = '';
        $info = self::getUserByIds(['name'],$ids);
        foreach ($info as $item){
            $nameString .= $item->name.',';
        }
        return rtrim($nameString,',');
    }

    /**
     * 获取多个email的字符串
     */
    public static function getEmailString ($ids){
        $emailString = '';
        $info = self::getUserByIds(['email','name'],$ids);
        foreach ($info as $item){

            $emailString .= decrypt_func($item->email, $item->name).',';
        }
        return rtrim($emailString,',');
    }
    /**
     * 获取多个phone的字符串
     */
    public static function getPhoneString ($ids){
        $phoneString = '';
        $info = self::getUserByIds(['phone','name'],$ids);
        foreach ($info as $item){

            $phoneString .= decrypt_func($item->phone, $item->name).',';
        }
        return rtrim($phoneString,',');
    }

    /**
     * 获取用户和角色信息
     * @param array $roleIds
     */
    public static function getUserWithRoles (array $roleIds){
        return self::select('users.*')->distinct()->join('assigned_roles as ar',function($join){
            $join->on(['ar.user_id'=>'users.id']);
        })->join('roles',function($join){
                $join->on(['roles.id'=>'ar.role_id']);
            })->whereIn('roles.id',$roleIds)->get();
    }

}
